home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / invent.c < prev    next >
C/C++ Source or Header  |  1993-01-05  |  47KB  |  1,831 lines

  1. /*    SCCS Id: @(#)invent.c    3.1    92/12/11    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. #include "artifact.h"
  7.  
  8. #define    NOINVSYM    '#'
  9. #define    CONTAINED_SYM    '>'    /* designator for inside a container */
  10.  
  11. #ifdef OVL1
  12. static void NDECL(reorder_invent);
  13. static boolean FDECL(mergable,(struct obj *,struct obj *));
  14. static int FDECL(merged,(struct obj *,struct obj *,int));
  15. #endif /* OVL1 */
  16. STATIC_DCL void FDECL(assigninvlet,(struct obj *));
  17. STATIC_DCL void FDECL(unlinkinv,(struct obj*));
  18. STATIC_DCL void FDECL(compactify,(char *));
  19. STATIC_PTR int FDECL(ckunpaid,(struct obj *));
  20. #ifdef OVLB
  21. static struct obj *FDECL(find_unpaid,(struct obj *,struct obj **));
  22. static boolean NDECL(wearing_armor);
  23. static boolean FDECL(is_worn,(struct obj *));
  24. #endif /* OVLB */
  25. STATIC_DCL char FDECL(obj_to_let,(struct obj *));
  26.  
  27. #ifdef OVLB
  28.  
  29. static int lastinvnr = 51;    /* 0 ... 51 (never saved&restored) */
  30.  
  31. char inv_order[] = {    /* manipulated in options.c, used below */
  32.     AMULET_CLASS, WEAPON_CLASS, ARMOR_CLASS, FOOD_CLASS, SCROLL_CLASS,
  33.     SPBOOK_CLASS, POTION_CLASS, RING_CLASS, WAND_CLASS, TOOL_CLASS, 
  34.     GEM_CLASS, ROCK_CLASS, BALL_CLASS, CHAIN_CLASS, 0 };
  35.  
  36. #ifdef WIZARD
  37. /* wizards can wish for venom, which will become an invisible inventory
  38.  * item without this.  putting it in inv_order would mean venom would
  39.  * suddenly become a choice for all the inventory-class commands, which
  40.  * would probably cause mass confusion.  the test for inventory venom
  41.  * is only WIZARD and not wizard because the wizard can leave venom lying
  42.  * around on a bones level for normal players to find.
  43.  */
  44. static char venom_inv[] = { VENOM_CLASS, 0 };    /* (constant) */
  45. #endif
  46.  
  47. STATIC_OVL void
  48. assigninvlet(otmp)
  49. register struct obj *otmp;
  50. {
  51.     boolean inuse[52];
  52.     register int i;
  53.     register struct obj *obj;
  54.  
  55.     for(i = 0; i < 52; i++) inuse[i] = FALSE;
  56.     for(obj = invent; obj; obj = obj->nobj) if(obj != otmp) {
  57.         i = obj->invlet;
  58.         if('a' <= i && i <= 'z') inuse[i - 'a'] = TRUE; else
  59.         if('A' <= i && i <= 'Z') inuse[i - 'A' + 26] = TRUE;
  60.         if(i == otmp->invlet) otmp->invlet = 0;
  61.     }
  62.     if((i = otmp->invlet) &&
  63.         (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z')))
  64.         return;
  65.     for(i = lastinvnr+1; i != lastinvnr; i++) {
  66.         if(i == 52) { i = -1; continue; }
  67.         if(!inuse[i]) break;
  68.     }
  69.     otmp->invlet = (inuse[i] ? NOINVSYM :
  70.             (i < 26) ? ('a'+i) : ('A'+i-26));
  71.     lastinvnr = i;
  72. }
  73.  
  74. #endif /* OVLB */
  75. #ifdef OVL1
  76.  
  77. /* note: assumes ASCII; toggling a bit puts lowercase in front of uppercase */
  78. #define inv_rank(o) ((o)->invlet ^ 040)
  79.  
  80. /* sort the inventory; used by addinv() and doorganize() */
  81. static void
  82. reorder_invent()
  83. {
  84.     struct obj *otmp, *prev, *next;
  85.     boolean need_more_sorting;
  86.  
  87.     do {
  88.         /*
  89.          * We expect at most one item to be out of order, so this
  90.          * isn't nearly as inefficient as it may first appear.
  91.          */
  92.         need_more_sorting = FALSE;
  93.         for (otmp = invent, prev = 0; otmp; ) {
  94.         next = otmp->nobj;
  95.         if (next && inv_rank(next) < inv_rank(otmp)) {
  96.             need_more_sorting = TRUE;
  97.             if (prev) prev->nobj = next;
  98.             else      invent = next;
  99.             otmp->nobj = next->nobj;
  100.             next->nobj = otmp;
  101.             prev = next;
  102.         } else {
  103.             prev = otmp;
  104.             otmp = next;
  105.         }
  106.         }
  107.     } while (need_more_sorting);
  108. }
  109.  
  110. #undef inv_rank
  111.  
  112. /* merge obj with otmp and delete obj if types agree */
  113. STATIC_OVL int
  114. merged(otmp, obj, lose)
  115. register struct obj *otmp, *obj;
  116. register int lose;
  117. {
  118.     if(mergable(otmp, obj)) {
  119.         /* Approximate age: we do it this way because if we were to
  120.          * do it "accurately" (merge only when ages are identical)
  121.          * we'd wind up never merging any corpses.
  122.          * otmp->age = otmp->age*(1-proportion) + obj->age*proportion;
  123.          */
  124.         otmp->age = ((otmp->age*otmp->quan) + (obj->age*obj->quan))
  125.             / (otmp->quan + obj->quan);
  126.         otmp->quan += obj->quan;
  127.         otmp->owt += obj->owt;
  128.         if(!otmp->onamelth && obj->onamelth)
  129.             otmp = oname(otmp, ONAME(obj), 1);
  130.         if(lose) freeobj(obj);
  131.         obfree(obj,otmp);    /* free(obj), bill->otmp */
  132.         return(1);
  133.     } else    return(0);
  134. }
  135.  
  136. struct obj *
  137. addinv(obj)
  138. register struct obj *obj;
  139. {
  140.     register struct obj *otmp, *prev;
  141.  
  142.     if (obj->otyp == GOLD_PIECE) {
  143.         u.ugold += obj->quan;
  144.         flags.botl = 1;
  145.         return obj;
  146.     } else if (obj->otyp == AMULET_OF_YENDOR) {
  147.         if (u.uhave.amulet) impossible ("already have amulet?");
  148.         u.uhave.amulet = 1;
  149.     } else if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
  150.         if (u.uhave.menorah) impossible ("already have candelabrum?");
  151.         u.uhave.menorah = 1;
  152.     } else if (obj->otyp == BELL_OF_OPENING) {
  153.         if (u.uhave.bell) impossible ("already have silver bell?");
  154.         u.uhave.bell = 1;
  155.     } else if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
  156.         if (u.uhave.book) impossible ("already have the book?");
  157.         u.uhave.book = 1;
  158. #ifdef MULDGN
  159.     } else if (is_quest_artifact(obj)) {
  160.         if (u.uhave.questart) impossible ("already have the artifact?");
  161.         u.uhave.questart = 1;
  162.         artitouch();
  163.         set_artifact_intrinsic(obj, 1, W_ART);
  164. #endif
  165.     } else if(obj->oartifact) {
  166.         set_artifact_intrinsic(obj, 1, W_ART);
  167.     }
  168.     /* merge if possible; find end of chain in the process */
  169.     for (prev = 0, otmp = invent; otmp; prev = otmp, otmp = otmp->nobj)
  170.         if (merged(otmp, obj, 0)) {
  171.         obj = otmp;
  172.         goto added;
  173.         }
  174.     /* didn't merge, so insert into chain */
  175.     if (flags.invlet_constant || !prev) {
  176.         if (flags.invlet_constant) assigninvlet(obj);
  177.         obj->nobj = invent;        /* insert at beginning */
  178.         invent = obj;
  179.         if (flags.invlet_constant) reorder_invent();
  180.     } else {
  181.         prev->nobj = obj;        /* insert at end */
  182.         obj->nobj = 0;
  183.     }
  184.  
  185. added:
  186.     if (obj->otyp == LUCKSTONE
  187.         || (obj->oartifact && spec_ability(obj, SPFX_LUCK))) {
  188.         /* new luckstone must be in inventory by this point
  189.          * for correct calculation */
  190.         if (stone_luck(TRUE) >= 0) u.moreluck = LUCKADD;
  191.         else u.moreluck = -LUCKADD;
  192.     } else if (obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP)
  193.         check_lamps();
  194.     update_inventory();
  195.     return(obj);
  196. }
  197.  
  198. #endif /* OVL1 */
  199. #ifdef OVLB
  200.  
  201. /* Add an item to the inventory unless we're fumbling, and give a message.
  202.  * If there aren't any free inventory slots, we'll drop it instead.
  203.  * If both success and failure messages are NULL, then we're just doing the
  204.  * fumbling/slot-limit checking for a silent grab.
  205.  * Note: will drop the whole bunch if the object merges first.
  206.  */
  207. struct obj *
  208. hold_another_object(obj, drop_fmt, drop_arg, hold_msg)
  209. struct obj *obj;
  210. const char *drop_fmt, *drop_arg, *hold_msg;
  211. {
  212.     long oquan = obj->quan;
  213.     if (!Blind) obj->dknown = 1;    /* maximize mergibility */
  214.     if (Fumbling) {
  215.         if (drop_fmt) pline(drop_fmt, drop_arg);
  216.         dropy(obj);
  217.     } else {
  218.         obj = addinv(obj);
  219.         if (inv_cnt() > 52
  220.             || ((obj->otyp != LOADSTONE || !obj->cursed)
  221.             && near_capacity() >= OVERLOADED)) {
  222.             if (drop_fmt) pline(drop_fmt, drop_arg);
  223.             dropx(obj);
  224.         } else {
  225.             if (hold_msg || drop_fmt) prinv(hold_msg, obj, oquan);
  226.         }
  227.     }
  228.     return obj;
  229. }
  230.  
  231. void
  232. useup(obj)
  233. register struct obj *obj;
  234. {
  235.     /*  Note:  This works correctly for containers because they */
  236.     /*       (containers) don't merge.                */
  237.     if(obj->quan > 1L){
  238. #ifndef NO_SIGNAL
  239.         obj->in_use = FALSE;    /* no longer in use */
  240. #endif
  241.         obj->quan--;
  242.         obj->owt = weight(obj);
  243.     } else {
  244.         setnotworn(obj);
  245.         freeinv(obj);
  246.         obfree(obj, (struct obj *) 0);    /* deletes contents also */
  247.     }
  248. }
  249.  
  250. #endif /* OVLB */
  251. #ifdef OVL3
  252.  
  253. /* used by freeinv and doorganize to do list manipulation */
  254. STATIC_OVL
  255. void
  256. unlinkinv(obj)
  257. register struct obj *obj;
  258. {
  259.     register struct obj *otmp;
  260.  
  261.     if(obj == invent)
  262.         invent = invent->nobj;
  263.     else {
  264.         for(otmp = invent; otmp->nobj != obj; otmp = otmp->nobj)
  265.             if(!otmp->nobj) panic("unlinkinv");
  266.         otmp->nobj = obj->nobj;
  267.     }
  268.     obj->nobj = 0;
  269. }
  270.  
  271. void
  272. freeinv(obj)
  273. register struct obj *obj;
  274. {
  275.     unlinkinv(obj);
  276.  
  277.     if (obj->otyp == GOLD_PIECE) {
  278.         u.ugold -= obj->quan;
  279.         flags.botl = 1;
  280.         return;
  281.     } else if (obj->otyp == AMULET_OF_YENDOR) {
  282.         if (!u.uhave.amulet) impossible ("don't have amulet?");
  283.         u.uhave.amulet = 0;
  284.     } else if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
  285.         if (!u.uhave.menorah) impossible ("don't have candelabrum?");
  286.         u.uhave.menorah = 0;
  287.     } else if (obj->otyp == BELL_OF_OPENING) {
  288.         if (!u.uhave.bell) impossible ("don't have silver bell?");
  289.         u.uhave.bell = 0;
  290.     } else if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
  291.         if (!u.uhave.book) impossible ("don't have the book?");
  292.         u.uhave.book = 0;
  293. #ifdef MULDGN
  294.     } else if (is_quest_artifact(obj)) {
  295.         if(!u.uhave.questart) impossible ("don't have the artifact?");
  296.         u.uhave.questart = 0;
  297.         set_artifact_intrinsic(obj, 0, W_ART);
  298. #endif
  299.     } else if (obj->oartifact) {
  300.         set_artifact_intrinsic(obj, 0, W_ART);
  301.     } else if (obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP
  302.            || obj->otyp == BRASS_LANTERN) {
  303.         if (obj->lamplit) {
  304.             obj->lamplit = 0;
  305.             if (!Blind) pline("%s goes out!", The(xname(obj)));
  306.         }
  307.         check_lamps();
  308.     } else if (obj->otyp == LOADSTONE) {
  309.         curse(obj);
  310.     } else if (obj->otyp == LUCKSTONE
  311.            || (obj->oartifact && spec_ability(obj, SPFX_LUCK))) {
  312.         int luckbon = stone_luck(TRUE);
  313.         if (!luckbon && !carrying(LUCKSTONE)) u.moreluck = 0;
  314.         else if (luckbon >= 0) u.moreluck = LUCKADD;
  315.         else u.moreluck = -LUCKADD;
  316.         flags.botl = 1;
  317.     }
  318.     update_inventory();
  319. }
  320.  
  321. void
  322. delallobj(x, y)
  323. int x, y;
  324. {
  325.     struct obj *otmp, *otmp2;
  326.  
  327.     for (otmp = level.objects[x][y]; otmp; otmp = otmp2) {
  328.         otmp2 = otmp->nexthere;
  329.         if (otmp == uball)
  330.             unpunish();
  331.         if (otmp == uchain)
  332.             continue;
  333.         delobj(otmp);
  334.     }
  335. }
  336.  
  337. #endif /* OVL3 */
  338. #ifdef OVL2
  339.  
  340. /* destroy object in fobj chain (if unpaid, it remains on the bill) */
  341. void
  342. delobj(obj)
  343. register struct obj *obj;
  344. {
  345. #ifdef WALKIES
  346.     if(obj->otyp == LEASH && obj->leashmon != 0) o_unleash(obj);
  347. #endif
  348.     freeobj(obj);
  349.     newsym(obj->ox,obj->oy);
  350.     obfree(obj, (struct obj *) 0);    /* frees contents also */
  351. }
  352.  
  353. /* unlink obj from chain starting with fobj */
  354. void
  355. freeobj(obj)
  356. register struct obj *obj;
  357. {
  358.     register struct obj *otmp;
  359.  
  360.     if (obj == fobj)
  361.         fobj = fobj->nobj;
  362.     else {
  363.         for(otmp = fobj; otmp; otmp = otmp->nobj)
  364.         if (otmp->nobj == obj) {
  365.             otmp->nobj = obj->nobj;
  366.             break;
  367.         }
  368.         if (!otmp) panic("error in freeobj");
  369.     }
  370.     remove_object(obj);
  371. }
  372.  
  373. #endif /* OVL2 */
  374. #ifdef OVL0
  375.  
  376. struct obj *
  377. sobj_at(n,x,y)
  378. register int n, x, y;
  379. {
  380.     register struct obj *otmp;
  381.  
  382.     for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
  383.         if(otmp->otyp == n)
  384.             return(otmp);
  385.     return((struct obj *)0);
  386. }
  387.  
  388. #endif /* OVL0 */
  389. #ifdef OVLB
  390.  
  391. int
  392. carried(obj)
  393. register struct obj *obj;
  394. {
  395.     register struct obj *otmp;
  396.  
  397.     for(otmp = invent; otmp; otmp = otmp->nobj)
  398.         if(otmp == obj) return(1);
  399.     return(0);
  400. }
  401.  
  402. struct obj *
  403. carrying(type)
  404. register int type;
  405. {
  406.     register struct obj *otmp;
  407.  
  408.     for(otmp = invent; otmp; otmp = otmp->nobj)
  409.         if(otmp->otyp == type)
  410.             return(otmp);
  411.     return((struct obj *) 0);
  412. }
  413.  
  414. boolean
  415. have_lizard()
  416. {
  417.     register struct obj *otmp;
  418.  
  419.     for(otmp = invent; otmp; otmp = otmp->nobj)
  420.         if(otmp->otyp == CORPSE && otmp->corpsenm == PM_LIZARD)
  421.             return(TRUE);
  422.     return(FALSE);
  423. }
  424.  
  425. struct obj *
  426. o_on(id, objchn)
  427. unsigned int id;
  428. register struct obj *objchn;
  429. {
  430.     struct obj *temp;
  431.  
  432.     while(objchn) {
  433.         if(objchn->o_id == id) return(objchn);
  434.         if (Is_container(objchn) && (temp = o_on(id,objchn->cobj)))
  435.             return temp;
  436.         objchn = objchn->nobj;
  437.     }
  438.     return((struct obj *) 0);
  439. }
  440.  
  441. boolean
  442. obj_here(obj, x, y)
  443. register struct obj *obj;
  444. int x, y;
  445. {
  446.     register struct obj *otmp;
  447.  
  448.     for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
  449.         if(obj == otmp) return(TRUE);
  450.     return(FALSE);
  451. }
  452.  
  453. #endif /* OVLB */
  454. #ifdef OVL2
  455.  
  456. struct obj *
  457. g_at(x,y)
  458. register int x, y;
  459. {
  460.     register struct obj *obj = level.objects[x][y];
  461.     while(obj) {
  462.         if (obj->otyp == GOLD_PIECE) return obj;
  463.         obj = obj->nexthere;
  464.     }
  465.     return((struct obj *)0);
  466. }
  467.  
  468. #endif /* OVL2 */
  469. #ifdef OVLB
  470.  
  471. /* Make a gold object from the hero's gold. */
  472. struct obj *
  473. mkgoldobj(q)
  474. register long q;
  475. {
  476.     register struct obj *otmp;
  477.  
  478.     otmp = mksobj(GOLD_PIECE, FALSE, FALSE);
  479.     u.ugold -= q;
  480.     otmp->quan = q;
  481.     otmp->owt = weight(otmp);
  482.     flags.botl = 1;
  483.     return(otmp);
  484. }
  485.  
  486. #endif /* OVLB */
  487. #ifdef OVL1
  488.  
  489. STATIC_OVL void
  490. compactify(buf)
  491. register char *buf;
  492. /* compact a string of inventory letters by dashing runs of letters */
  493. {
  494.     register int i1 = 1, i2 = 1;
  495.     register char ilet, ilet1, ilet2;
  496.  
  497.     ilet2 = buf[0];
  498.     ilet1 = buf[1];
  499.     buf[++i2] = buf[++i1];
  500.     ilet = buf[i1];
  501.     while(ilet) {
  502.         if(ilet == ilet1+1) {
  503.             if(ilet1 == ilet2+1)
  504.                 buf[i2 - 1] = ilet1 = '-';
  505.             else if(ilet2 == '-') {
  506.                 buf[i2 - 1] = ++ilet1;
  507.                 buf[i2] = buf[++i1];
  508.                 ilet = buf[i1];
  509.                 continue;
  510.             }
  511.         }
  512.         ilet2 = ilet1;
  513.         ilet1 = ilet;
  514.         buf[++i2] = buf[++i1];
  515.         ilet = buf[i1];
  516.     }
  517. }
  518.  
  519. /*
  520.  * getobj returns:
  521.  *    struct obj *xxx:    object to do something with.
  522.  *    (struct obj *) 0    error return: no object.
  523.  *    &zeroobj        explicitly no object (as in w-).
  524.  */
  525. struct obj *
  526. getobj(let,word)
  527. register const char *let,*word;
  528. {
  529.     register struct obj *otmp;
  530.     register char ilet;
  531.     char buf[BUFSZ], qbuf[QBUFSZ];
  532.     char lets[BUFSZ];
  533.     register int foo = 0;
  534.     register char *bp = buf;
  535.     xchar allowcnt = 0;    /* 0, 1 or 2 */
  536.     boolean allowgold = FALSE, usegold = FALSE;
  537.         /* Two possibilities: they can't use gold because it's illegal,
  538.          * or they can't use gold because they don't have any.
  539.          */
  540.     boolean allowall = FALSE;
  541.     boolean allownone = FALSE;
  542.     xchar foox = 0;
  543.     long cnt;
  544.     boolean prezero = FALSE;
  545.  
  546.     if(*let == ALLOW_COUNT) let++, allowcnt = 1;
  547.     if(*let == GOLD_CLASS) let++,
  548.         usegold = TRUE, allowgold = (u.ugold ? TRUE : FALSE);
  549. #ifdef POLYSELF
  550.     /* Equivalent of an "ugly check" for gold */
  551.     if (usegold && !strcmp(word, "eat") && !metallivorous(uasmon))
  552.         usegold = allowgold = FALSE;
  553. #endif
  554.     if(*let == ALL_CLASSES) let++, allowall = TRUE;
  555.     if(*let == ALLOW_NONE) let++, allownone = TRUE;
  556.     /* "ugly check" for reading fortune cookies, part 1 */
  557.     if(allowall && !strcmp(word, "read")) allowall = FALSE;
  558.  
  559.     if(allownone) *bp++ = '-';
  560.     if(allowgold) *bp++ = def_oc_syms[GOLD_CLASS];
  561.     if(bp > buf && bp[-1] == '-') *bp++ = ' ';
  562.  
  563.     ilet = 'a';
  564.     for(otmp = invent; otmp; otmp = otmp->nobj){
  565.         if(!*let || index(let, otmp->oclass)) {
  566.         bp[foo++] = flags.invlet_constant ? otmp->invlet : ilet;
  567.  
  568.         /* ugly check: remove inappropriate things */
  569.         if((!strcmp(word, "take off") &&
  570.             (!(otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL))
  571.              || (otmp==uarm && uarmc)
  572. #ifdef TOURIST
  573.              || (otmp==uarmu && (uarm || uarmc))
  574. #endif
  575.             ))
  576.         || (!strcmp(word, "wear") &&
  577.              (otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)))
  578.                             /* already worn */
  579.         || (!strcmp(word, "wield") &&
  580.             (otmp->owornmask & W_WEP))
  581.             ) {
  582.             foo--;
  583.             foox++;
  584.         }
  585.  
  586.         /* Second ugly check; unlike the first it won't trigger an
  587.          * "else" in "you don't have anything else to ___".
  588.          */
  589.         else if ((!strcmp(word, "wear") &&
  590.             (otmp->oclass == TOOL_CLASS &&
  591.              otmp->otyp != BLINDFOLD && otmp->otyp != TOWEL))
  592. #ifdef POLYSELF
  593.         || (!strcmp(word, "eat") && !is_edible(otmp))
  594. #endif
  595.         || (!strcmp(word, "can") &&
  596.             (otmp->otyp != CORPSE))
  597.         || (!strcmp(word, "write with") &&
  598.             (otmp->oclass == TOOL_CLASS &&
  599.              otmp->otyp != MAGIC_MARKER && otmp->otyp != TOWEL))
  600.         || (!strcmp(word, "rub") &&
  601.             (otmp->oclass == TOOL_CLASS &&
  602.              otmp->otyp != OIL_LAMP && otmp->otyp != MAGIC_LAMP &&
  603.              otmp->otyp != BRASS_LANTERN))
  604.         || (!strcmp(word, "wield") &&
  605.             (otmp->oclass == TOOL_CLASS &&
  606.              otmp->otyp != PICK_AXE && otmp->otyp != UNICORN_HORN))
  607.             )
  608.             foo--;
  609.         } else {
  610.  
  611.         /* "ugly check" for reading fortune cookies, part 2 */
  612.         if ((!strcmp(word, "read") && otmp->otyp == FORTUNE_COOKIE))
  613.             allowall = TRUE;
  614.         }
  615.  
  616.         if(ilet == 'z') ilet = 'A'; else ilet++;
  617.     }
  618.     bp[foo] = 0;
  619.     if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0;
  620.     Strcpy(lets, bp);    /* necessary since we destroy buf */
  621.     if(foo > 5)            /* compactify string */
  622.         compactify(bp);
  623.  
  624.     if(!foo && !allowall && !allowgold && !allownone) {
  625.         You("don't have anything %sto %s.",
  626.             foox ? "else " : "", word);
  627.         return((struct obj *)0);
  628.     }
  629.     for(;;) {
  630.         cnt = 0;
  631.         if (allowcnt == 2) allowcnt = 1;  /* abort previous count */
  632.         if(!buf[0]) {
  633.             Sprintf(qbuf, "What do you want to %s? [*]", word);
  634.         } else {
  635.             Sprintf(qbuf, "What do you want to %s? [%s or ?*]",
  636.                 word, buf);
  637.         }
  638. #ifdef REDO
  639.         if(!in_doagain)
  640.             ilet = yn_function(qbuf, NULL, '\0');
  641.         else
  642. #endif
  643.             ilet = readchar();
  644.         if(ilet == '0') prezero = TRUE;
  645.         while(digit(ilet) && allowcnt) {
  646. #ifdef REDO
  647.             if (ilet != '?' && ilet != '*')    savech(ilet);
  648. #endif
  649.             cnt = 10*cnt + (ilet - '0');
  650.             allowcnt = 2;    /* signal presence of cnt */
  651.             ilet = readchar();
  652.         }
  653.         if(digit(ilet)) {
  654.             pline("No count allowed with this command.");
  655.             continue;
  656.         }
  657.         if(index(quitchars,ilet)) {
  658.             if(flags.verbose)
  659.             pline("Never mind.");
  660.             return((struct obj *)0);
  661.         }
  662.         if(ilet == '-') {
  663.             return(allownone ? &zeroobj : (struct obj *) 0);
  664.         }
  665.         if(ilet == def_oc_syms[GOLD_CLASS]) {
  666.             if(!usegold){
  667.                 You("cannot %s gold.", word);
  668.                 return(struct obj *)0;
  669.             } else if (!allowgold) {
  670.                 You("are not carrying any gold.");
  671.                 return(struct obj *)0;
  672.             }
  673.             if(cnt == 0 && prezero) return((struct obj *)0);
  674.             /* Historic note: early Nethack had a bug which was
  675.              * first reported for Larn, where trying to drop 2^32-n
  676.              * gold pieces was allowed, and did interesting things
  677.              * to your money supply.  The LRS is the tax bureau
  678.              * from Larn.
  679.              */
  680.             if(cnt < 0) {
  681.     pline("The LRS would be very interested to know you have that much.");
  682.                 return(struct obj *)0;
  683.             }
  684.  
  685.             if(!(allowcnt == 2 && cnt < u.ugold))
  686.                 cnt = u.ugold;
  687.             return(mkgoldobj(cnt));
  688.         }
  689.         if(allowcnt == 2 && !strcmp(word,"throw")) {
  690.             /* permit counts for throwing gold, but don't accept
  691.              * counts for other things since the throw code will
  692.              * split off a single item anyway */
  693.             allowcnt = 1;
  694.             if(cnt == 0 && prezero) return((struct obj *)0);
  695.             if(cnt > 1) {
  696.                 You("can only throw one item at a time.");
  697.                 continue;
  698.             }
  699.         }
  700.         if(ilet == '?' || ilet == '*') {
  701.             ilet = display_inventory(ilet == '?' ? lets : NULL, FALSE);
  702.             if(!ilet) continue;
  703.             if(ilet == '\033') {
  704.             if(flags.verbose)
  705.                 pline("Never mind.");
  706.             return((struct obj *)0);
  707.             }
  708.             /* they typed a letter (not a space) at the prompt */
  709.         }
  710. #ifdef REDO
  711.         savech(ilet);
  712. #endif
  713.         if(flags.invlet_constant) {
  714.             for(otmp = invent; otmp; otmp = otmp->nobj)
  715.                 if(otmp->invlet == ilet) break;
  716.         } else {
  717.             if(ilet >= 'A' && ilet <= 'Z') ilet += 'z' - 'A' + 1;
  718.             ilet -= 'a';
  719.             for(otmp = invent; otmp && ilet;
  720.                     ilet--, otmp = otmp->nobj) ;
  721.         }
  722.         if(!otmp) {
  723.             You("don't have that object.");
  724.             continue;
  725.         } else if (cnt < 0 || otmp->quan < cnt) {
  726.             You("don't have that many!  You have only %ld.",
  727.                 otmp->quan);
  728.             continue;
  729.         }
  730.         break;
  731.     }
  732.     if(!allowall && let && !index(let,otmp->oclass)) {
  733.         pline(silly_thing_to, word);
  734.         return((struct obj *)0);
  735.     }
  736.     if(allowcnt == 2) {    /* cnt given */
  737.         if(cnt == 0) return (struct obj *)0;
  738.         if(cnt != otmp->quan) {
  739.             register struct obj *obj = splitobj(otmp, cnt);
  740.         /* Very ugly kludge necessary to prevent someone from trying
  741.          * to drop one of several loadstones and having the loadstone
  742.          * now be separate.
  743.          */
  744.             if (!strcmp(word, "drop") &&
  745.                 obj->otyp == LOADSTONE && obj->cursed)
  746.                 otmp->corpsenm = obj->invlet;
  747.             if(otmp == uwep) setuwep(obj);
  748.         }
  749.     }
  750.     return(otmp);
  751. }
  752.  
  753. #endif /* OVL1 */
  754. #ifdef OVLB
  755.  
  756. STATIC_PTR int
  757. ckunpaid(otmp)
  758. register struct obj *otmp;
  759. {
  760.     return((int)(otmp->unpaid));
  761. }
  762.  
  763. static boolean
  764. wearing_armor() {
  765.     return(uarm || uarmc || uarmf || uarmg || uarmh || uarms
  766. #ifdef TOURIST
  767.         || uarmu
  768. #endif
  769.         );
  770. }
  771.  
  772. static boolean
  773. is_worn(otmp)
  774. register struct obj *otmp;
  775. {
  776.     return(!!(otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL | W_WEP)));
  777. }
  778.  
  779. static const char NEARDATA removeables[] =
  780.     { ARMOR_CLASS, WEAPON_CLASS, RING_CLASS, AMULET_CLASS, TOOL_CLASS, 0 };
  781.  
  782. /* interactive version of getobj - used for Drop, Identify and */
  783. /* Takeoff (A). Return the number of times fn was called successfully */
  784. int
  785. ggetobj(word, fn, mx)
  786. register const char *word;
  787. register int FDECL((*fn),(OBJ_P)), mx;
  788. {
  789.     char buf[BUFSZ], qbuf[QBUFSZ];
  790.     register char *ip;
  791.     register char sym;
  792.     register int oletct = 0, iletct = 0;
  793.     register boolean allflag = FALSE;
  794.     char olets[20], ilets[20];
  795.     int FDECL((*ckfn),(OBJ_P)) = (int (*)()) 0;
  796.     xchar allowgold = (u.ugold && !strcmp(word, "drop")) ? 1 : 0; /* BAH */
  797.     register boolean takeoff = !strcmp(word, "take off");
  798.     struct obj *obj;
  799.     int unpaid, oc_of_sym;
  800.  
  801.     if(takeoff && !wearing_armor() && !uwep && !uamul &&
  802.             !uleft && !uright && !ublindf) {
  803.         You("are not wearing anything.");
  804.         return(0);
  805.     }
  806.     if(!invent && !allowgold){
  807.         You("have nothing to %s.", word);
  808.         return(0);
  809.     }
  810.  
  811.     if (allowgold) ilets[iletct++] = def_oc_syms[GOLD_CLASS];
  812.     ilets[iletct] = '\0';    /* terminate for index() */
  813.     unpaid = 0;
  814.     for (obj = invent; obj; obj = obj->nobj) {
  815.         sym = (char) def_oc_syms[(int) obj->oclass];
  816.         if (!index(ilets, sym) && (!takeoff || is_worn(obj))) {
  817.             ilets[iletct++] = sym;
  818.             /* necessary because of index() being used above */
  819.             ilets[iletct] = '\0';
  820.         }
  821.  
  822.         if (obj->unpaid) unpaid = 1;
  823.     }
  824.  
  825.     if (!takeoff && (unpaid || invent)) {
  826.         ilets[iletct++] = ' ';
  827.         if (unpaid) ilets[iletct++] = 'u';
  828.         if (invent) ilets[iletct++] = 'a';
  829.     }
  830.     ilets[iletct] = '\0';    /* outside the if to catch iletct==0 case */
  831.  
  832.     Sprintf(qbuf,"What kinds of thing do you want to %s? [%s]",
  833.         word, ilets);
  834.     getlin(qbuf, buf);
  835.     if(buf[0] == '\033') {
  836.         clear_nhwindow(WIN_MESSAGE);
  837.         return(0);
  838.     }
  839.     ip = buf;
  840.     olets[0] = 0;
  841.     while ((sym = *ip++) != 0) {
  842.         if(sym == ' ') continue;
  843.         oc_of_sym = def_char_to_objclass(sym);
  844.         if(takeoff && !(uwep && oc_of_sym == uwep->oclass)
  845.            && (oc_of_sym != MAXOCLASSES)) {
  846.             if(!index(removeables,oc_of_sym)) {
  847.             pline("Not applicable.");
  848.             return(0);
  849.             } else if(oc_of_sym == ARMOR_CLASS && !wearing_armor()) {
  850.             You("are not wearing any armor.");
  851.             return(0);
  852.             } else if(oc_of_sym == WEAPON_CLASS && !uwep) {
  853.             You("are not wielding anything.");
  854.             return(0);
  855.             } else if(oc_of_sym == RING_CLASS && !uright && !uleft) {
  856.             You("are not wearing rings.");
  857.             return(0);
  858.             } else if(oc_of_sym == AMULET_CLASS && !uamul) {
  859.             You("are not wearing an amulet.");
  860.             return(0);
  861.             } else if(oc_of_sym == TOOL_CLASS && !ublindf) {
  862.             You("are not wearing a blindfold.");
  863.             return(0);
  864.             }
  865.         }
  866.         if(oc_of_sym == GOLD_CLASS) {
  867.             if(allowgold == 1)
  868.                 (*fn)(mkgoldobj(u.ugold));
  869.             else if(!u.ugold)
  870.                 You("have no gold.");
  871.             allowgold = 2;
  872.         } else if(sym == 'a' || sym == 'A')
  873.             allflag = TRUE;
  874.         else if(sym == 'u' || sym == 'U')
  875.             ckfn = ckunpaid;
  876.         else if (oc_of_sym == MAXOCLASSES)
  877.             You("don't have any %c's.", sym);
  878.         else if (oc_of_sym != VENOM_CLASS) {/* venom doesn't show up */
  879.             if (!index(olets, oc_of_sym)) {
  880.                 olets[oletct++] = oc_of_sym;
  881.                 olets[oletct] = 0;
  882.             }
  883.         }
  884.     }
  885.     if(allowgold == 2 && !oletct)
  886.         return 1;    /* you dropped gold (or at least tried to) */
  887.     else
  888.         return askchain((struct obj **)&invent, olets, allflag,
  889.                 fn, ckfn, mx, word);
  890. }
  891.  
  892. /*
  893.  * Walk through the chain starting at objchn and ask for all objects
  894.  * with olet in olets (if nonNULL) and satisfying ckfn (if nonNULL)
  895.  * whether the action in question (i.e., fn) has to be performed.
  896.  * If allflag then no questions are asked. Max gives the max nr of
  897.  * objects to be treated. Return the number of objects treated.
  898.  */
  899. int
  900. askchain(objchn, olets, allflag, fn, ckfn, mx, word)
  901. struct obj **objchn;
  902. register int allflag, mx;
  903. register const char *olets, *word;    /* olets is an Obj Class char array */
  904. register int FDECL((*fn),(OBJ_P)), FDECL((*ckfn),(OBJ_P));
  905. {
  906.     register struct obj *otmp, *otmp2;
  907.     register char sym, ilet;
  908.     register int cnt = 0, dud = 0, tmp;
  909.     boolean takeoff, nodot, ident, ininv;
  910.     char qbuf[QBUFSZ];
  911.  
  912.     takeoff = !strcmp(word, "take off");
  913.     ident = !strcmp(word, "identify");
  914.     nodot = (!strcmp(word, "nodot") || !strcmp(word, "drop") ||
  915.          ident || takeoff);
  916.     ininv = (*objchn == invent);
  917.     /* Changed so the askchain is interrogated in the order specified.
  918.      * For example, if a person specifies =/ then first all rings will be
  919.      * asked about followed by all wands -dgk
  920.      */
  921. nextclass:
  922.     ilet = 'a'-1;
  923.     if ((*objchn)->otyp == GOLD_PIECE) ilet--;    /* extra iteration */
  924.     for (otmp = *objchn; otmp; otmp = otmp2) {
  925.         if(ilet == 'z') ilet = 'A'; else ilet++;
  926.         otmp2 = otmp->nobj;
  927.         if (olets && *olets && otmp->oclass != *olets) continue;
  928.         if(takeoff && !is_worn(otmp)) continue;
  929.         if(ckfn && !(*ckfn)(otmp)) continue;
  930.         if(!allflag) {
  931.             Strcpy(qbuf, ininv ?
  932.                 xprname(otmp, ilet, !nodot, 0L) : doname(otmp));
  933.             Strcat(qbuf, "?");
  934.             sym = (takeoff || ident || otmp->quan < 2L) ?
  935.                 nyaq(qbuf) : nyNaq(qbuf);
  936.         }
  937.         else    sym = 'y';
  938.  
  939.         if (sym == '#') {
  940.          /* Number was entered; split the object unless it corresponds
  941.             to 'none' or 'all'.  2 special cases: cursed loadstones and
  942.             welded weapons (eg, multiple daggers) will remain as merged
  943.             unit; done to avoid splitting an object that won't be
  944.             droppable (even if we're picking up rather than dropping).
  945.           */
  946.             if (!yn_number)
  947.             sym = 'n';
  948.             else {
  949.             sym = 'y';
  950.             if (yn_number < otmp->quan && !welded(otmp) &&
  951.                 (!otmp->cursed || otmp->otyp != LOADSTONE)) {
  952.                 struct obj *otmpx = splitobj(otmp, yn_number);
  953.                 if (!otmpx || otmpx->nobj != otmp2)
  954.                 impossible("bad object split in askchain");
  955.             }
  956.             }
  957.         }
  958.         switch(sym){
  959.         case 'a':
  960.             allflag = 1;
  961.         case 'y':
  962.             tmp = (*fn)(otmp);
  963.             if(tmp < 0) goto ret;
  964.             cnt += tmp;
  965.             if(--mx == 0) goto ret;
  966.         case 'n':
  967.             if(nodot) dud++;
  968.         default:
  969.             break;
  970.         case 'q':
  971.             goto ret;
  972.         }
  973.     }
  974.     if (olets && *olets && *++olets)
  975.         goto nextclass;
  976.     if(!takeoff && (dud || cnt)) pline("That was all.");
  977.     else if(!dud && !cnt) pline("No applicable objects.");
  978. ret:
  979.     return(cnt);
  980. }
  981.  
  982. #endif /* OVLB */
  983. #ifdef OVL2
  984.  
  985. STATIC_OVL char
  986. obj_to_let(obj)    /* should of course only be called for things in invent */
  987. register struct obj *obj;
  988. {
  989.     register struct obj *otmp;
  990.     register char ilet;
  991.  
  992.     if (obj->otyp == GOLD_PIECE)
  993.         return GOLD_SYM;
  994.     else if (flags.invlet_constant)
  995.         return obj->invlet;
  996.     ilet = 'a';
  997.     for(otmp = invent; otmp && otmp != obj; otmp = otmp->nobj)
  998.         if(++ilet > 'z') ilet = 'A';
  999.     return(otmp ? ilet : NOINVSYM);
  1000. }
  1001.  
  1002. /*
  1003.  * Print the indicated quantity of the given object.  If quan == 0L then use
  1004.  * the current quantity.
  1005.  */
  1006. void
  1007. prinv(prefix, obj, quan)
  1008. const char *prefix;
  1009. register struct obj *obj;
  1010. long quan;
  1011. {
  1012. #ifdef GCC_WARN
  1013.     long savequan = 0;
  1014. #else
  1015.     long savequan;
  1016. #endif
  1017.     if ( !prefix ) prefix = "";
  1018.     if (quan) {
  1019.         savequan = obj->quan;
  1020.         obj->quan = quan;
  1021.     }
  1022.     pline("%s%s%s",
  1023.           prefix, *prefix ? " " : "",
  1024.           xprname(obj, obj_to_let(obj), TRUE, 0L));
  1025.     if (quan) obj->quan = savequan;
  1026. }
  1027.  
  1028. #endif /* OVL2 */
  1029. #ifdef OVL1
  1030.  
  1031. char *
  1032. xprname(obj,let,dot,cost)
  1033. register struct obj *obj;
  1034. register char let;
  1035. register boolean dot;   /* append period; (dot && cost => Iu) */
  1036. register long cost;     /* cost (for inventory of unpaid or expended items) */
  1037. {
  1038. #ifdef LINT    /* handle static char li[BUFSZ]; */
  1039.     char li[BUFSZ];
  1040. #else
  1041.     static char li[BUFSZ];
  1042. #endif
  1043.     boolean use_invlet = flags.invlet_constant && let != CONTAINED_SYM;
  1044.     /*
  1045.      * If let is:
  1046.      *    *  Then obj == NULL and we are printing a total amount.
  1047.      *    >  Then the object is contained and doesn't have an inventory letter.
  1048.      */
  1049.     if (cost != 0 || let == '*') {
  1050.     /* if dot is true, we're doing Iu, otherwise Ix */
  1051.     Sprintf(li, "%c - %-45s %6ld zorkmid%s",
  1052.         (dot && use_invlet ? obj->invlet : let),
  1053.         (let != '*' ? doname(obj) : "Total:"), cost, plur(cost));
  1054.     } else if (obj->otyp == GOLD_PIECE) {
  1055.     Sprintf(li, "%ld gold piece%s%s", obj->quan, plur(obj->quan),
  1056.         (dot ? "." : ""));
  1057.     } else {
  1058.     /* ordinary inventory display or pickup message */
  1059.     Sprintf(li, "%c - %s",
  1060.         (use_invlet ? obj->invlet : let),
  1061.         doname(obj));
  1062.     if(dot) Strcat(li,".");
  1063.     }
  1064.     return li;
  1065. }
  1066.  
  1067. #endif /* OVL1 */
  1068. #ifdef OVLB
  1069.  
  1070. int
  1071. ddoinv()
  1072. {
  1073.     (void) display_inventory(NULL, FALSE);
  1074.     return 0;
  1075. }
  1076.  
  1077. /*
  1078.  *  find_unpaid()
  1079.  *
  1080.  *  Scan the given list of objects.  If last_found is NULL, return the first
  1081.  *  unpaid object found.  If last_found is not NULL, then skip over unpaid
  1082.  *  objects until last_found is reached, then set last_found to NULL so the
  1083.  *  next unpaid object is returned.  This routine recursively follows
  1084.  *  containers.
  1085.  */
  1086. static struct obj *
  1087. find_unpaid(list, last_found)
  1088.     struct obj *list, **last_found;
  1089. {
  1090.     struct obj *obj;
  1091.  
  1092.     while (list) {
  1093.     if (list->unpaid) {
  1094.         if (*last_found) {
  1095.         /* still looking for previous unpaid object */
  1096.         if (list == *last_found)
  1097.             *last_found = (struct obj *) 0;
  1098.         } else
  1099.         return (*last_found = list);
  1100.     }
  1101.     if (Is_container(list) && list->cobj) {
  1102.         if ((obj = find_unpaid(list->cobj, last_found)) != 0)
  1103.         return obj;
  1104.     }
  1105.     list = list->nobj;
  1106.     }
  1107.     return (struct obj *) 0;
  1108. }
  1109.  
  1110. /*
  1111.  *  If lets == NULL or "", list all objects in the inventory.  Otherwise,
  1112.  *  list all objects with object classes that match the order in lets.
  1113.  *  The last letter could possibly be a '>' which means list unpaid contained
  1114.  *  objects.
  1115.  *  Returns the letter identifier of a selected item, or 0 (nothing was
  1116.  *  selected), or '\033' (the menu was cancelled).
  1117.  */
  1118. char
  1119. display_inventory(lets,show_cost)
  1120. register const char *lets;
  1121. boolean show_cost;
  1122. {
  1123.     register struct obj *otmp;
  1124.     struct obj *z_obj;
  1125.     register char ilet;
  1126.     char *invlet = inv_order;
  1127.     int classcount;
  1128. #if defined(LINT) || defined(GCC_WARN)
  1129.     int save_unpaid = 0;
  1130. #else
  1131.     int save_unpaid;
  1132. #endif
  1133.     long cost, totcost;
  1134.     boolean do_containers = FALSE;
  1135.  
  1136.     if(!invent){
  1137.         pline("Not carrying anything.");
  1138.         return 0;
  1139.     }
  1140.     if (lets != NULL) {
  1141.         int ct = strlen(lets); /* count number of inventory slots to show */
  1142.         /* If we've got unpaid items in containers, count all unpaid
  1143.            objects.  At least one won't be in any inventory slot. */
  1144.         do_containers = (ct && lets[ct-1] == CONTAINED_SYM);
  1145.         if (do_containers && ct == 1) ct = count_unpaid(invent);
  1146.         /* if only one item of interest, use pline instead of menus */
  1147.         if (ct == 1) {
  1148.         if (do_containers) {    /* single non-inventory object */
  1149.             z_obj = (struct obj *) 0;
  1150.             if ((otmp = find_unpaid(invent, &z_obj)) != 0)
  1151.             pline(xprname(otmp, CONTAINED_SYM, TRUE,
  1152.                      (show_cost ? unpaid_cost(otmp) : 0L)));
  1153.             else
  1154.             impossible(
  1155.             "display_inventory: no singular unpaid contained objects");
  1156.         } else {
  1157.             for(otmp = invent; otmp; otmp = otmp->nobj) {
  1158.             if (otmp->invlet == lets[0]) {
  1159.                 pline(xprname(otmp, lets[0], TRUE,
  1160.                      (show_cost ? unpaid_cost(otmp) : 0L)));
  1161.                 break;
  1162.             }
  1163.             }
  1164.         }
  1165.         return 0;
  1166.         }
  1167.     }
  1168.  
  1169.     start_menu(WIN_INVEN);
  1170.     cost = totcost = 0;
  1171. nextclass:
  1172.     classcount = 0;
  1173.     ilet = 'a';
  1174.     for(otmp = invent; otmp; otmp = otmp->nobj) {
  1175.         if(flags.invlet_constant) ilet = otmp->invlet;
  1176.         if(!lets || !*lets || index(lets, ilet)) {
  1177.             if (!flags.sortpack || otmp->oclass == *invlet) {
  1178.                 if (flags.sortpack && !classcount) {
  1179.                 add_menu(WIN_INVEN, 0, ATR_INVERSE,
  1180.                      let_to_name(*invlet, show_cost));
  1181.                 classcount++;
  1182.                 }
  1183.                 if (show_cost) {
  1184.                 totcost += cost = unpaid_cost(otmp);
  1185.                 /* suppress "(unpaid)" suffix */
  1186.                 save_unpaid = otmp->unpaid;
  1187.                 otmp->unpaid = 0;
  1188.                 }
  1189.                 add_menu(WIN_INVEN, ilet, 0,
  1190.                      xprname(otmp, ilet, TRUE, cost));
  1191.                 if (show_cost)  otmp->unpaid = save_unpaid;
  1192.             }
  1193.         }
  1194.         if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A';
  1195.     }
  1196.     if (flags.sortpack) {
  1197.         if (*++invlet) goto nextclass;
  1198. #ifdef WIZARD
  1199.         if (--invlet != venom_inv) {
  1200.             invlet = venom_inv;
  1201.             goto nextclass;
  1202.         }
  1203. #endif
  1204.     }
  1205.  
  1206.     /* right now, we only do this for unpaid items, so always do cost */
  1207.     if (do_containers) {
  1208.         if (flags.sortpack) add_menu(WIN_INVEN, 0, ATR_INVERSE,
  1209.                      let_to_name(CONTAINED_SYM, 1));
  1210.         /*
  1211.          *  Search through the container objects in the inventory for
  1212.          *  unpaid items.  Note that we check each container, not
  1213.          *  the invent list.  This is because the invent list could
  1214.          *  have unpaid items that have been already listed.
  1215.          */
  1216.         for (otmp = invent; otmp; otmp = otmp->nobj) {
  1217.         if (Is_container(otmp) && otmp->cobj) {
  1218.             z_obj = (struct obj *) 0;    /* haven't found any */
  1219.             while (find_unpaid(otmp->cobj, (struct obj **)&z_obj)) {
  1220.             totcost += cost = unpaid_cost(z_obj);
  1221.             save_unpaid = z_obj->unpaid;
  1222.             z_obj->unpaid = 0;    /* suppress "(unpaid)" suffix */
  1223.             add_menu(WIN_INVEN, 0, 0,
  1224.                  xprname(z_obj, CONTAINED_SYM, TRUE, cost));
  1225.             z_obj->unpaid = save_unpaid;
  1226.             }
  1227.         }
  1228.         }
  1229.     }
  1230.  
  1231.     if (show_cost) {
  1232.         /* give 'Totals' line */
  1233.         add_menu(WIN_INVEN, 0, 0, "");
  1234.         add_menu(WIN_INVEN, 0, 0,
  1235.              xprname((struct obj *)0, '*', FALSE, totcost));
  1236.     }
  1237.     end_menu(WIN_INVEN, '\033', "\033 ", NULL);
  1238.     return select_menu(WIN_INVEN);
  1239. }
  1240.  
  1241. /*
  1242.  *  Returns the number of unpaid items within the given list.  This includes
  1243.  *  contained objects.
  1244.  */
  1245. int
  1246. count_unpaid(list)
  1247.     struct obj *list;
  1248. {
  1249.     int count = 0;
  1250.  
  1251.     while (list) {
  1252.     if (list->unpaid) count++;
  1253.     if (Is_container(list) && list->cobj)
  1254.         count += count_unpaid(list->cobj);
  1255.     list = list->nobj;
  1256.     }
  1257.     return count;
  1258. }
  1259.  
  1260. int
  1261. dotypeinv()                /* free after Robert Viduya */
  1262. /* Changed to one type only, so you don't have to type return */
  1263. {
  1264.     char c, ilet;
  1265.     char stuff[BUFSZ];
  1266.     register int stct;
  1267.     register struct obj *otmp;
  1268.     boolean billx = *u.ushops && doinvbill(0);
  1269.     boolean do_unpd = FALSE;
  1270.     int unpd, class;
  1271.  
  1272.     if (!invent && !u.ugold && !billx) {
  1273.         You("aren't carrying anything.");
  1274.         return 0;
  1275.     }
  1276.  
  1277.     Strcpy(stuff, "What type of object do you want an inventory of? [");
  1278.     /* collect a list of classes of objects carried, for use as a prompt */
  1279.     stct = collect_obj_classes(eos(stuff), invent, FALSE, (u.ugold != 0));
  1280.     unpd = count_unpaid(invent);
  1281.     if(unpd) Strcat(stuff, "u");
  1282.     if(billx) Strcat(stuff, "x");
  1283.     Strcat(stuff, "]");
  1284.  
  1285.     if(stct > 1) {
  1286.       c = yn_function(stuff, NULL, '\0');
  1287. #ifdef REDO
  1288.         savech(c);
  1289. #endif
  1290.         if(c == '\0') {
  1291.         clear_nhwindow(WIN_MESSAGE);
  1292.         return 0;
  1293.         }
  1294.     } else
  1295.         c = stuff[0];
  1296.  
  1297.     if(c == 'x' || c == 'X') {
  1298.         if(billx)
  1299.         (void) doinvbill(1);
  1300.         else
  1301.         pline("No used-up objects on the shopping bill.");
  1302.         return(0);
  1303.     }
  1304.  
  1305.     if (c == 'u' || c == 'U') {
  1306.         if (!unpd) {
  1307.         You("are not carrying any unpaid objects.");
  1308.         return(0);
  1309.         }
  1310.         do_unpd = TRUE;
  1311.     }
  1312.  
  1313.     class = def_char_to_objclass(c);    /* change to object class */
  1314.  
  1315.     if(class == GOLD_CLASS)
  1316.         return(doprgold());
  1317.  
  1318.     /* collect all items which match the selected objclass */
  1319.     stct = 0;
  1320.     ilet = 'a';
  1321.     for (otmp = invent; otmp; otmp = otmp->nobj) {
  1322.         if(flags.invlet_constant) ilet = otmp->invlet;
  1323.         if (class == otmp->oclass || (do_unpd && otmp->unpaid)) {
  1324.         stuff[stct++] = ilet;
  1325.         --unpd;    /* decrement unpaid count */
  1326.         }
  1327.         if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A';
  1328.     }
  1329.     /* unpd is now the number of unpaid contained objects */
  1330.     if (do_unpd && unpd)
  1331.         stuff[stct++] = CONTAINED_SYM;    /* list contained unpaid items */
  1332.  
  1333.     stuff[stct] = '\0';
  1334.     if(stct == 0)
  1335.         You("have no such objects.");
  1336.     else
  1337.         (void) display_inventory(stuff, do_unpd);
  1338.  
  1339.     return(0);
  1340. }
  1341.  
  1342. /* look at what is here */
  1343. int
  1344. dolook()
  1345. {
  1346.     register struct obj *otmp, *otmp0;
  1347.     struct trap *trap;
  1348.     const char *verb = Blind ? "feel" : "see";
  1349.     const char *dfeature = (char*) 0;
  1350.     char fbuf[BUFSZ], fbuf2[BUFSZ];
  1351.     int ct;
  1352.     boolean no_article = FALSE;
  1353.     winid tmpwin;
  1354.  
  1355.     if(u.uswallow) {
  1356.         You("%s no objects here.", verb);
  1357.         return(!!Blind);
  1358.     }
  1359.     read_engr_at(u.ux, u.uy); /* Eric Backus */
  1360.     if ((trap = t_at(u.ux,u.uy)) && trap->tseen)
  1361.         pline("There is a%s here.", traps[trap->ttyp]);
  1362.  
  1363.     otmp0 = level.objects[u.ux][u.uy];
  1364.  
  1365.     if(IS_DOOR(levl[u.ux][u.uy].typ))  {
  1366.         switch(levl[u.ux][u.uy].doormask) {
  1367.             case D_NODOOR:
  1368.             dfeature = "doorway"; break;
  1369.             case D_ISOPEN:
  1370.             dfeature = "open door"; break;
  1371.             case D_BROKEN:
  1372.             dfeature = "broken door"; break;
  1373.             default:
  1374.             dfeature = "closed door";
  1375.         }
  1376.     } else if(IS_FOUNTAIN(levl[u.ux][u.uy].typ))
  1377.         /* added by GAN 10/30/86 */
  1378.         dfeature = "fountain";
  1379.     else if(IS_THRONE(levl[u.ux][u.uy].typ))
  1380.         dfeature = "opulent throne";
  1381.     else if(is_lava(u.ux,u.uy))
  1382.         dfeature = "molten lava",  no_article = TRUE;
  1383.     else if(is_ice(u.ux,u.uy))
  1384.         dfeature = "ice",  no_article = TRUE;
  1385.     else if(is_pool(u.ux,u.uy) && !Underwater)
  1386.         dfeature = "pool of water";
  1387. #ifdef SINKS
  1388.     else if(IS_SINK(levl[u.ux][u.uy].typ))
  1389.         dfeature = "kitchen sink";
  1390. #endif
  1391.     else if(IS_ALTAR(levl[u.ux][u.uy].typ))  {
  1392.         Sprintf(fbuf2, "altar to %s (%s)",
  1393.             a_gname(),
  1394.             align_str(Amask2align(levl[u.ux][u.uy].altarmask
  1395.                                 & ~AM_SHRINE)));
  1396.         dfeature = fbuf2;
  1397.     } else if(u.ux == xupstair && u.uy == yupstair)
  1398.         dfeature = "stairway up";
  1399.     else if(u.ux == xdnstair && u.uy == ydnstair)
  1400.         dfeature = "stairway down";
  1401.     else if(u.ux == sstairs.sx && u.uy == sstairs.sy) {
  1402.         if (sstairs.up)
  1403.             dfeature = "stairway up";
  1404.         else
  1405.             dfeature = "stairway down";
  1406.     } else if(u.ux == xupladder && u.uy == yupladder)
  1407.         dfeature = "ladder up";
  1408.     else if(u.ux == xdnladder && u.uy == ydnladder)
  1409.         dfeature = "ladder down";
  1410.     else if (levl[u.ux][u.uy].typ == DRAWBRIDGE_DOWN)
  1411.         dfeature = "lowered drawbridge";
  1412.  
  1413.     if (Blind) {
  1414.         You("try to feel what is %s.",
  1415.             Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) ?
  1416.             "floating here" :
  1417.             "lying here on the floor");
  1418.          if (Levitation &&
  1419.             !Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz)) {
  1420.             pline("But you can't reach it!");
  1421.             return(0);
  1422.          }
  1423.     }
  1424.  
  1425.     if (dfeature)
  1426.         Sprintf(fbuf, "There is %s%s here.",
  1427.             no_article ? "" :
  1428.                 index(vowels,dfeature[0]) ? "an " : "a ",
  1429.             dfeature);
  1430.  
  1431.     if(!otmp0 || (is_pool(u.ux,u.uy) && !Underwater)) {
  1432.             if(dfeature) pline(fbuf);
  1433.         if(Blind || !dfeature)
  1434.             You("%s no objects here.", verb);
  1435.         return(!!Blind);
  1436.     }
  1437.     /* we know there is something here */
  1438.  
  1439.     /* find out if there is more than one object there */
  1440.     for (ct = 0, otmp = otmp0; otmp; otmp = otmp->nexthere)
  1441.         if (++ct > 1) break;
  1442.  
  1443.     if (ct == 1) {
  1444.         if (dfeature) pline(fbuf);
  1445.         You("%s here %s.", verb, doname(otmp0));
  1446.     } else {
  1447.         display_nhwindow(NHW_MESSAGE, FALSE);
  1448.         tmpwin = create_nhwindow(NHW_MENU);
  1449.         if(dfeature) {
  1450.         putstr(tmpwin, 0, fbuf);
  1451.         putstr(tmpwin, 0, "");
  1452.         }
  1453.         putstr(tmpwin, 0, "Things that are here:");
  1454.         for(otmp = otmp0; otmp; otmp = otmp->nexthere) {
  1455.         putstr(tmpwin, 0, doname(otmp));
  1456.  
  1457.         if(Blind  && !uarmg &&
  1458. #ifdef POLYSELF
  1459.                 !resists_ston(uasmon) &&
  1460. #endif
  1461.                 (otmp->otyp == CORPSE &&
  1462.                     otmp->corpsenm == PM_COCKATRICE)) {
  1463. #if defined(POLYSELF)
  1464.             if(poly_when_stoned(uasmon)) {
  1465.             You("touched the cockatrice corpse with your bare hands.");
  1466.             (void) polymon(PM_STONE_GOLEM);
  1467.             } else
  1468. #endif
  1469.             {
  1470.             pline("Touching the cockatrice corpse is a fatal mistake...");
  1471.             You("turn to stone...");
  1472.             killer_format = KILLED_BY_AN;
  1473.             killer = "cockatrice corpse";
  1474.             done(STONING);
  1475.             }
  1476.         }
  1477.         }
  1478.         display_nhwindow(tmpwin, TRUE);
  1479.         destroy_nhwindow(tmpwin);
  1480.     }
  1481.     return(!!Blind);
  1482. }
  1483.  
  1484. #endif /* OVLB */
  1485. #ifdef OVL1
  1486.  
  1487. void
  1488. stackobj(obj)
  1489. register struct obj *obj;
  1490. {
  1491.     register struct obj *otmp;
  1492.  
  1493.     for(otmp = level.objects[obj->ox][obj->oy]; otmp; otmp = otmp->nexthere)
  1494.         if(otmp != obj && merged(obj,otmp,1))
  1495.             break;
  1496.     return;
  1497. }
  1498.  
  1499. static boolean
  1500. mergable(otmp, obj)    /* returns TRUE if obj  & otmp can be merged */
  1501.     register struct obj *otmp, *obj;
  1502. {
  1503.     if(obj->otyp != otmp->otyp || obj->unpaid != otmp->unpaid ||
  1504.        obj->spe != otmp->spe || obj->dknown != otmp->dknown ||
  1505.        (obj->bknown != otmp->bknown && pl_character[0] != 'P') ||
  1506.        obj->cursed != otmp->cursed || obj->blessed != otmp->blessed ||
  1507.        obj->no_charge != otmp->no_charge ||
  1508.        obj->obroken != otmp->obroken ||
  1509.        obj->otrapped != otmp->otrapped ||
  1510.        obj->oeroded != otmp->oeroded)
  1511.         return(FALSE);
  1512.  
  1513.     if((obj->oclass==WEAPON_CLASS || obj->oclass==ARMOR_CLASS) &&
  1514.        (obj->oerodeproof!=otmp->oerodeproof || obj->rknown!=otmp->rknown))
  1515.         return FALSE;
  1516.  
  1517.     if(obj->oclass == FOOD_CLASS && (obj->oeaten != otmp->oeaten ||
  1518.         obj->orotten != otmp->orotten))
  1519.         return(FALSE);
  1520.  
  1521.     if(obj->otyp == CORPSE || obj->otyp == EGG || obj->otyp == TIN) {
  1522.         if((obj->corpsenm != otmp->corpsenm) ||
  1523.             (ONAME(obj) && strcmp(ONAME(obj), ONAME(otmp))))
  1524.                 return FALSE;
  1525.     }
  1526.  
  1527. /* if they have names, make sure they're the same */
  1528.     if ( (obj->onamelth != otmp->onamelth &&
  1529.         ((obj->onamelth && otmp->onamelth) || obj->otyp == CORPSE)
  1530.          ) ||
  1531.         (obj->onamelth &&
  1532.             strncmp(ONAME(obj), ONAME(otmp), (int)obj->onamelth)))
  1533.         return FALSE;
  1534.  
  1535.     if(obj->oartifact != otmp->oartifact) return FALSE;
  1536.  
  1537.     if(obj->known == otmp->known ||
  1538.         !objects[otmp->otyp].oc_uses_known) {
  1539.         return(objects[obj->otyp].oc_merge);
  1540.     } else return(FALSE);
  1541. }
  1542.  
  1543. #endif /* OVL1 */
  1544. #ifdef OVLB
  1545.  
  1546. int
  1547. doprgold(){
  1548.     if(!u.ugold)
  1549.         You("do not carry any gold.");
  1550.     else
  1551.         You("are carrying %ld gold piece%s.", u.ugold, plur(u.ugold));
  1552.     return 0;
  1553. }
  1554.  
  1555. int
  1556. doprwep()
  1557. {
  1558.     if(!uwep) You("are empty %s.", body_part(HANDED));
  1559.     else prinv(NULL, uwep, 0L);
  1560.     return 0;
  1561. }
  1562.  
  1563. int
  1564. doprarm(){
  1565.     if(!wearing_armor())
  1566.         You("are not wearing any armor.");
  1567.     else {
  1568. #ifdef TOURIST
  1569.         char lets[8];
  1570. #else
  1571.         char lets[7];
  1572. #endif
  1573.         register int ct = 0;
  1574.  
  1575. #ifdef TOURIST
  1576.         if(uarmu) lets[ct++] = obj_to_let(uarmu);
  1577. #endif
  1578.         if(uarm) lets[ct++] = obj_to_let(uarm);
  1579.         if(uarmc) lets[ct++] = obj_to_let(uarmc);
  1580.         if(uarmh) lets[ct++] = obj_to_let(uarmh);
  1581.         if(uarms) lets[ct++] = obj_to_let(uarms);
  1582.         if(uarmg) lets[ct++] = obj_to_let(uarmg);
  1583.         if(uarmf) lets[ct++] = obj_to_let(uarmf);
  1584.         lets[ct] = 0;
  1585.         (void) display_inventory(lets, FALSE);
  1586.     }
  1587.     return 0;
  1588. }
  1589.  
  1590. int
  1591. doprring(){
  1592.     if(!uleft && !uright)
  1593.         You("are not wearing any rings.");
  1594.     else {
  1595.         char lets[3];
  1596.         register int ct = 0;
  1597.  
  1598.         if(uleft) lets[ct++] = obj_to_let(uleft);
  1599.         if(uright) lets[ct++] = obj_to_let(uright);
  1600.         lets[ct] = 0;
  1601.         (void) display_inventory(lets, FALSE);
  1602.     }
  1603.     return 0;
  1604. }
  1605.  
  1606. int
  1607. dopramulet(){
  1608.     if (!uamul)
  1609.         You("are not wearing an amulet.");
  1610.     else
  1611.         prinv(NULL, uamul, 0L);
  1612.     return 0;
  1613. }
  1614.  
  1615. int
  1616. doprtool(){
  1617.     register struct obj *otmp;
  1618.     register int ct=0;
  1619.     char lets[3]; /* Maximum: pick-axe, blindfold */
  1620.  
  1621.     for(otmp = invent; otmp; otmp = otmp->nobj) {
  1622.         if (((otmp->owornmask & W_TOOL) && otmp->oclass==TOOL_CLASS)
  1623.            || (otmp==uwep &&
  1624.            (otmp->otyp==PICK_AXE || otmp->otyp==TIN_OPENER)))
  1625.             lets[ct++] = obj_to_let(otmp);
  1626.     }
  1627.     lets[ct] = 0;
  1628.     if (!ct) You("are not using any tools.");
  1629.     else (void) display_inventory(lets, FALSE);
  1630.     return 0;
  1631. }
  1632.  
  1633. /*
  1634.  * uses up an object that's on the floor, charging for it as necessary
  1635.  */
  1636. void
  1637. useupf(obj)
  1638. register struct obj *obj;
  1639. {
  1640.     register struct obj *otmp;
  1641.  
  1642.     /* burn_floor_paper() keeps an object pointer that it tries to
  1643.      * useupf() multiple times, so obj must survive if plural */
  1644.     if(obj->quan > 1L)
  1645.         otmp = splitobj(obj, obj->quan - 1L);
  1646.     else
  1647.         otmp = obj;
  1648.     if(costly_spot(otmp->ox, otmp->oy)) {
  1649.         if(index(u.urooms, *in_rooms(otmp->ox, otmp->oy, 0)))
  1650.             addtobill(otmp, FALSE, FALSE, FALSE);
  1651.         else (void)stolen_value(otmp, otmp->ox, otmp->oy, FALSE, FALSE);
  1652.     }
  1653.     delobj(otmp);
  1654. }
  1655.  
  1656. #endif /* OVLB */
  1657. #ifdef OVL1
  1658.  
  1659. extern const char obj_symbols[];    /* o_init.c */
  1660. /*
  1661.  * Conversion from a symbol to a string for printing object classes.
  1662.  * This must match the array obj_symbols[].
  1663.  */
  1664. static const char NEARDATA *names[] = {
  1665.     "Illegal objects", "Amulets", "Coins", "Comestibles", "Weapons",
  1666.     "Tools", "Iron balls", "Chains", "Boulders/Statues", "Armor",
  1667.     "Potions", "Scrolls", "Wands", "Spellbooks", "Rings", "Gems"
  1668. };
  1669.  
  1670. static const char NEARDATA oth_symbols[] = {
  1671. #ifdef WIZARD
  1672.     VENOM_CLASS,
  1673. #endif
  1674.     CONTAINED_SYM,
  1675.     '\0'
  1676. };
  1677.  
  1678. static const char NEARDATA *oth_names[] = {
  1679. #ifdef WIZARD
  1680.     "Venoms",
  1681. #endif
  1682.     "Bagged/Boxed items"
  1683. };
  1684.  
  1685. char *
  1686. let_to_name(let,unpaid)
  1687. char let;
  1688. boolean unpaid;
  1689. {
  1690.     const char *class_name;
  1691.     const char *pos = index(obj_symbols, let);
  1692.     int len;
  1693.     static char NEARDATA *buf = NULL;
  1694.     static unsigned NEARDATA bufsiz = 0;
  1695.  
  1696.     if (pos)
  1697.         class_name = names[pos - obj_symbols];
  1698.     else if ((pos = index(oth_symbols, let)) != 0)
  1699.         class_name = oth_names[pos - oth_symbols];
  1700.     else
  1701.         class_name = names[0];
  1702.  
  1703.     len = strlen(class_name)
  1704.          + (unpaid ? sizeof("unpaid_") : 1);    /* count terminating NUL */
  1705.     if (len > bufsiz) {
  1706.         if (buf)  free((genericptr_t)buf),  buf = NULL;
  1707.         bufsiz = len + 10; /* add slop to avoid incremental reallocations */
  1708.         buf = (char *) alloc(bufsiz);
  1709.     }
  1710.     if (unpaid)
  1711.         Strcat(strcpy(buf, "Unpaid "), class_name);
  1712.     else
  1713.         Strcpy(buf, class_name);
  1714.     return (buf);
  1715. }
  1716.  
  1717. #endif /* OVL1 */
  1718. #ifdef OVLB 
  1719.  
  1720. void
  1721. reassign()
  1722. {
  1723.     register int i;
  1724.     register struct obj *obj;
  1725.  
  1726.     for(obj = invent, i = 0; obj; obj = obj->nobj, i++)
  1727.         obj->invlet = (i < 26) ? ('a'+i) : ('A'+i-26);
  1728.     lastinvnr = i;
  1729. }
  1730.  
  1731. #endif /* OVLB */
  1732. #ifdef OVL1
  1733. int
  1734. doorganize()    /* inventory organizer by Del Lamb */
  1735. {
  1736.     register struct obj *obj, *otmp;
  1737.     register int ix, cur;
  1738.     register char let;
  1739.     char alphabet[52+1], buf[52+1];
  1740.     char qbuf[QBUFSZ];
  1741.     char allow_all[2];
  1742.     const char *adj_type;
  1743.  
  1744.     /* check to see if the inventory is of the fixed kind */
  1745.     if (!flags.invlet_constant ) {
  1746.         pline("Sorry, only fixed inventories can be adjusted.");
  1747.         return(0);
  1748.     }
  1749. #if 0
  1750.     /* check to see if the inventory has any gaps left in it */
  1751.     if (inv_cnt() >= 52) {
  1752.         pline("Sorry, no available letters for adjustment.");
  1753.         return(0);
  1754.     }
  1755. #endif
  1756.     /* get a pointer to the object the user wants to organize */
  1757.     allow_all[0] = ALL_CLASSES; allow_all[1] = '\0';
  1758.     if (!(obj = getobj(allow_all,"adjust"))) return(0);
  1759.  
  1760.     /* initialize the list with all upper and lower case letters */
  1761.     for (let = 'a', ix = 0;  let <= 'z';) alphabet[ix++] = let++;
  1762.     for (let = 'A', ix = 26; let <= 'Z';) alphabet[ix++] = let++;
  1763.     alphabet[52] = 0;
  1764.  
  1765.     /* blank out all the letters currently in use in the inventory */
  1766.     /* except those that will be merged with the selected object   */
  1767.     for (otmp = invent; otmp; otmp = otmp->nobj)
  1768.         if (otmp != obj && !mergable(otmp,obj))
  1769.             if (otmp->invlet <= 'Z')
  1770.                 alphabet[(otmp->invlet) - 'A' + 26] = ' ';
  1771.             else    alphabet[(otmp->invlet) - 'a']        = ' ';
  1772.  
  1773.     /* compact the list by removing all the blanks */
  1774.     for (ix = cur = 0; ix <= 52; ix++)
  1775.         if (alphabet[ix] != ' ') buf[cur++] = alphabet[ix];
  1776.  
  1777.     /* and by dashing runs of letters */
  1778.     if(cur > 5) compactify(buf);
  1779.  
  1780.     /* get new letter to use as inventory letter */
  1781.     for (;;) {
  1782.         Sprintf(qbuf, "Adjust letter to what [%s]?",buf);
  1783.         let = yn_function(qbuf, NULL, '\0');
  1784.         if(index(quitchars,let)) {
  1785.             pline("Never mind.");
  1786.             return(0);
  1787.         }
  1788.         if (let == '@' || !letter(let))
  1789.             pline("Select an inventory slot letter.");
  1790.         else
  1791.             break;
  1792.     }
  1793.  
  1794.     /* change the inventory and print the resulting item */
  1795.     adj_type = "Moving:";
  1796.  
  1797.     /*
  1798.      * don't use freeinv/addinv to avoid double-touching artifacts,
  1799.      * dousing lamps, losing luck, cursing loadstone, etc.
  1800.      */
  1801.     unlinkinv(obj);
  1802.  
  1803.     for (otmp = invent; otmp;)
  1804.         if (merged(otmp,obj,0)) {
  1805.             adj_type = "Merging:";
  1806.             obj = otmp;
  1807.             otmp = otmp->nobj;
  1808.             unlinkinv(obj);
  1809.         } else {
  1810.             if (otmp->invlet == let) {
  1811.                 adj_type = "Swapping:";
  1812.                 otmp->invlet = obj->invlet;
  1813.             }
  1814.             otmp = otmp->nobj;
  1815.         }
  1816.  
  1817.     /* inline addinv (assuming flags.invlet_constant and !merged) */
  1818.     obj->invlet = let;
  1819.     obj->nobj = invent; /* insert at beginning */
  1820.     invent = obj;
  1821.     reorder_invent();
  1822.  
  1823.     prinv(adj_type, obj, 0L);
  1824.     update_inventory();
  1825.     return(0);
  1826. }
  1827.  
  1828. #endif /* OVL1 */
  1829.  
  1830. /*invent.c*/
  1831.